package com.ccl.keyassistant.db;
/*
 *项目名     keyassistant
 *包名       com.ccl.keyassistant.db
 *文件名     DBHelper
 *创建者     ccl
 *创建时间   2019-03-16 15:05
 *注解       工程数据库助手类, 我們在自己封裝一些東西的時候可以以Manager類的型式，也可以以Helper的形式，仿照慕课网课程实现
 */

import android.content.ContentValues;
import android.content.Context;
import android.text.TextUtils;

import com.ccl.keyassistant.utils.L;
import com.ccl.keyassistant.utils.StaticClass;


import net.sqlcipher.database.SQLiteDatabase;
import net.sqlcipher.database.SQLiteOpenHelper;

import java.util.ArrayList;

public final class DBHelper extends SQLiteOpenHelper {

    private static Context mContext;
    private static final String DATABASE_NAME = "keyassistant.db";
    private static final int DB_VERSION = 1;

    private static DBHelper helper = null;

    /**
     * 字段公共类型
     */
    public static final String INTEGER_TYPE = " integer ";
    public static final String TEXT_TYPE = " TEXT ";
    /**
     * 表公共字段
     */
    public static final String ID = " _id ";
    public static final String TIME = " create_time ";


    /**
     * manual_key表
     */

    public static final String TABLE_KEY = " key ";
    //账户或文件名
    public static final String FILENAME = " file_name ";
    public static final String PASSWORD = " password ";
    public static final String REMARK = " remark ";
    public static final String FILEHASH = " file_hash ";
    public static final String EN_TYPE = " en_type ";


    public DBHelper(Context context) {
        super(context, DATABASE_NAME, null, DB_VERSION);
    }

    public static synchronized DBHelper getInstance(Context context) {
        if (helper == null) {
            helper = new DBHelper(context);
        }
        return helper;
    }

    /**
     * 调用getInstance时先为其初始化一个Context
     *
     * @param context
     */
    public static void setContext(Context context) {
        mContext = context;
    }

    /**
     * 完成表结构的初始化操作
     *
     * @param db
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.beginTransaction();
        try {
            createAllTables(db);
            db.setTransactionSuccessful();
            L.i("onCreate success");
        } catch (Exception e) {
            e.getMessage();
        } finally {
            db.endTransaction();
        }
    }


    /**
     * 当版本更新时可以更新数据库
     *
     * @param sqLiteDatabase
     * @param oldVersion
     * @param newVersion
     */
    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
        //根据老的数据库版本名来升级数据库,增量升级
        switch (oldVersion) {
            //此处不应该有break; 保证版本跳跃时也可以全部更新，例如:由oldVersion为1直接到version 5
            case 1:
            case 2:
            default:
                break;
        }
    }

    /**
     * 创建所有的表
     *
     * @param db
     */
    private void createAllTables(SQLiteDatabase db) {
        //创建key表 ID,createtime自动添加
        String[] columns = new String[]{
                FILENAME + TEXT_TYPE, PASSWORD + TEXT_TYPE, REMARK + TEXT_TYPE,
                FILEHASH + TEXT_TYPE, EN_TYPE + TEXT_TYPE
        };

        String[] pin = new String[]{
                " pincode " + TEXT_TYPE
        };

        createTable(db, TABLE_KEY, columns);
        createTable(db, "pincode", pin);
    }


    /**
     * 完成创建数据库表的操作
     *
     * @param db      数据库
     * @param table   要创建的表名
     * @param columns 数据库表的列
     */
    private void createTable(SQLiteDatabase db, String table, String[] columns) {
        String createTable = " create table if not exists ";
        String primaryKey = " Integer primary key autoincrement ";
        char leftBracket = '(';
        char rightBracket = ')';
        char comma = ',';

        StringBuffer sql = new StringBuffer();
        if (db == null || TextUtils.isEmpty(table)) {
            L.w("db == null || table == null");
            return;
        }
        sql.append(createTable).append(table).append(leftBracket).
                append(ID).append(primaryKey).append(comma);
        for (String column : columns) {
            if (!TextUtils.isEmpty(column)) {
                sql.append(column);
                sql.append(comma);
            }
        }

        sql.append(TIME).append(rightBracket);
        try {
            L.i("createTable " + sql.toString());
            db.execSQL(sql.toString().trim());
        } catch (Exception e) {
            e.getMessage();
        }
    }


    /**
     * 关闭数据库
     *
     * @param db
     * @return true  关闭成功
     */
    public boolean closeDataBase(SQLiteDatabase db) {
        if (db != null && db.isOpen()) {
            db.close();
            return true;
        }
        return false;
    }


    /**
     * 插入数据
     *
     * @param table          表名
     * @param nullColumnHack 当列名为空时的填充值
     * @param values
     * @return
     */
    public synchronized long insert(final String table, final String nullColumnHack,
                                    final ContentValues values) {
        SQLiteDatabase database = null;
        try {
            database = getWritableDatabase(StaticClass.MMSM);
            L.i("mmsm:"+StaticClass.MMSM);
            L.i("database: " + database);
            return database.insert(table, nullColumnHack, values);
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        } finally {
            closeDataBase(database);
        }
    }


//    nullColumnHack： 当values参数为空或者里面没有内容的时候，我们insert是会失败的
//    （底层数据库不允许插入一个空行），为了防止这种情况，我们要在这里指定一个 列名，
//    到时候如果发现将要插入的行为空行时，就会将你指定的这个列名的值设为null，然后再向数据库中插入。

    /**
     * 插入大量数据
     *
     * @param table
     * @param nullColumnHack
     * @param contentValues
     * @return
     */
    public synchronized boolean insert(final String table, final String nullColumnHack,
                                       final ArrayList<ContentValues> contentValues) {
        SQLiteDatabase database = null;
        boolean result = true;
        try {
            database = getWritableDatabase(StaticClass.MMSM);
            L.i("mmsm:"+StaticClass.MMSM);
            database.beginTransaction();
            for (ContentValues values : contentValues) {
                if ((database.insert(table, nullColumnHack, values)) < 0) {
                    result = false;
                    break;
                }
            }

            if (result) {
                database.setTransactionSuccessful();
            }
        } catch (Exception e) {
            e.getMessage();
        } finally {
            database.endTransaction();
            closeDataBase(database);
        }

        return result;
    }


    /**
     * 删除数据
     *
     * @param table
     * @param whereClause 删除条件
     * @param whereArgs   删除条件对应的值
     * @return
     */
    public int delete(final String table, final String whereClause, final String[] whereArgs) {
        SQLiteDatabase database = null;
        try {
            database = getWritableDatabase(StaticClass.MMSM);
            return database.delete(table, whereClause, whereArgs);
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        } finally {
            closeDataBase(database);
        }
    }


    /**
     * 更新数据
     *
     * @param table
     * @param values      要更新的数据
     * @param whereClause 更新条件
     * @param whereArgs   条件对应的值
     * @return
     */
    public synchronized int update(final String table, final ContentValues values,
                                   final String whereClause, final String[] whereArgs) {
        SQLiteDatabase database = null;
        try {
            database = getWritableDatabase(StaticClass.MMSM);
            return database.update(table, values, whereClause, whereArgs);
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        } finally {
            closeDataBase(database);
        }
    }

}
